package com.zbkj.crmeb.chant.service.impl;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.common.CommonPage;
import com.crmeb.core.exception.CrmebException;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.utils.ProductConvertUtil;
import com.zbkj.crmeb.chant.dao.ChannelDiscountDao;
import com.zbkj.crmeb.chant.dto.ChannelDiscountDTO;
import com.zbkj.crmeb.chant.model.ChannelDiscount;
import com.zbkj.crmeb.chant.model.ChannelDiscountGoods;
import com.zbkj.crmeb.chant.request.ChannelDiscountRequest;
import com.zbkj.crmeb.chant.service.ChannelDiscountGoodsService;
import com.zbkj.crmeb.chant.service.ChannelDiscountService;
import com.zbkj.crmeb.store.model.StoreProduct;
import com.zbkj.crmeb.store.service.StoreProductService;
import com.zbkj.crmeb.system.service.SystemAdminService;

import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * 满减送
 * @author daigb
 * @date:  2023-01-06 16:26
 */
@Service
@Slf4j
public class ChannelDiscountServiceImpl extends ServiceImpl<ChannelDiscountDao, ChannelDiscount> implements ChannelDiscountService {
    @Resource
    private ChannelDiscountDao channelDiscountDao;
    @Resource
    private ChannelDiscountGoodsService channelDiscountGoodsService;
    @Resource
    private SystemAdminService systemAdminService;
    @Resource
    private StoreProductService storeProductService;
    @Autowired
    private ProductConvertUtil productConvertUtil;
    
    /**
     * 列表查询(无分页)
     */
	@Override
	public List<ChannelDiscountDTO> listEntity(Integer merId, ChannelDiscountRequest channelDiscountRequest) {
		Integer state = channelDiscountRequest.getState();
		Date time = new Date();

		// 查询条件
        LambdaQueryWrapper<ChannelDiscount> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(ChannelDiscount :: getMerId, merId);
        lambdaQueryWrapper.like(null != channelDiscountRequest.getName(), ChannelDiscount :: getName, channelDiscountRequest.getName());
        lambdaQueryWrapper.eq(null != channelDiscountRequest.getStatus(), ChannelDiscount :: getStatus, channelDiscountRequest.getStatus());
		if(null != state) {
			// 未开始
			if(0 == state.intValue()) {
		        lambdaQueryWrapper.gt(ChannelDiscount :: getStartTime, time);
			// 进行中
			} else if(1 == state.intValue()) {
				lambdaQueryWrapper.and(qr -> 
                qr.le(ChannelDiscount :: getStartTime, time).ge(ChannelDiscount :: getEndTime, time).
                or().
                isNull(ChannelDiscount :: getStartTime)
                );
				lambdaQueryWrapper.ne(ChannelDiscount :: getStatus, 0);
//		        lambdaQueryWrapper.le(ChannelDiscount :: getStartTime, time);
//		        lambdaQueryWrapper.ge(ChannelDiscount :: getEndTime, time);
			// 已结束
			} else if(-1 == state.intValue()) {
				lambdaQueryWrapper.and(e -> e.lt(ChannelDiscount :: getEndTime, time)
						.or().eq(ChannelDiscount :: getStatus, 0));
			}
		}
        
		List<ChannelDiscount> channelDiscounts = this.list(lambdaQueryWrapper);
		// 数据处理
		List<ChannelDiscountDTO> channelDiscountDTOs = new ArrayList<>();
		for(ChannelDiscount channelDiscount : channelDiscounts) {
			ChannelDiscountDTO channelDiscountDTO = new ChannelDiscountDTO();
			BeanUtils.copyProperties(channelDiscount, channelDiscountDTO);
			if(null == channelDiscount.getStartTime() || null == channelDiscount.getEndTime()) {
				state = 1;
			} else {
				if(-1 == time.compareTo(channelDiscount.getStartTime())) {
					state = 0;
				} else if(1 == time.compareTo(channelDiscount.getStartTime()) && -1 == time.compareTo(channelDiscount.getEndTime())) {
					state = 1;
				} else if(1 == time.compareTo(channelDiscount.getEndTime())) {
					state = -1;
				}
			}
			channelDiscountDTO.setState(state);
			// 转义为文本描述
			convertDescription(channelDiscount, channelDiscountDTO);
			// 查询活动下商品信息
	        List<ChannelDiscountGoods> channelDiscountGoodsList = channelDiscountGoodsService.list(Wrappers.<ChannelDiscountGoods>lambdaQuery()
	        		.eq(ChannelDiscountGoods :: getDiscountId, channelDiscount.getId())
	        		);
	        channelDiscountDTO.setChannelDiscountGoodsList(channelDiscountGoodsList);
			
			channelDiscountDTOs.add(channelDiscountDTO);
		}
		
		return channelDiscountDTOs;
	}

	/**
	 * 分页查询
	 */
	@Override
	public PageInfo<ChannelDiscountDTO> pageEntity(Integer merId, ChannelDiscountRequest channelDiscountRequest) {
		Integer state = channelDiscountRequest.getState();
		Date time = new Date();

		Page<ChannelDiscount> storeProductPage = PageHelper.startPage(channelDiscountRequest.getPageNow(), channelDiscountRequest.getPageSize());
		// 查询条件
        LambdaQueryWrapper<ChannelDiscount> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(ChannelDiscount :: getMerId, merId);
        lambdaQueryWrapper.like(null != channelDiscountRequest.getName(), ChannelDiscount :: getName, channelDiscountRequest.getName());
        lambdaQueryWrapper.eq(null != channelDiscountRequest.getStatus(), ChannelDiscount :: getStatus, channelDiscountRequest.getStatus());
		if(null != state) {
			// 未开始
			if(0 == state.intValue()) {
		        lambdaQueryWrapper.gt(ChannelDiscount :: getStartTime, time);
			// 进行中
			} else if(1 == state.intValue()) {
				lambdaQueryWrapper.and(qr ->
						qr.le(ChannelDiscount :: getStartTime, time).ge(ChannelDiscount :: getEndTime, time).
								or().
								isNull(ChannelDiscount :: getStartTime)
				);
				lambdaQueryWrapper.ne(ChannelDiscount :: getStatus, 0);
			// 已结束
			} else if(-1 == state.intValue()) {
		        lambdaQueryWrapper.and(e -> e.lt(ChannelDiscount :: getEndTime, time)
						.or().eq(ChannelDiscount :: getStatus, 0));
			}
		}
        
		List<ChannelDiscount> channelDiscounts = this.list(lambdaQueryWrapper);
		// 数据处理
		List<ChannelDiscountDTO> channelDiscountDTOs = new ArrayList<>();
		for(ChannelDiscount channelDiscount : channelDiscounts) {
			ChannelDiscountDTO channelDiscountDTO = new ChannelDiscountDTO();
			BeanUtils.copyProperties(channelDiscount, channelDiscountDTO);
			if(null == channelDiscount.getStartTime() || null == channelDiscount.getEndTime()) {
				state = 1;
			} else {
				if(-1 == time.compareTo(channelDiscount.getStartTime())) {
					state = 0;
				} else if(1 == time.compareTo(channelDiscount.getStartTime()) && -1 == time.compareTo(channelDiscount.getEndTime())) {
					state = 1;
				} else if(1 == time.compareTo(channelDiscount.getEndTime())) {
					state = -1;
				}
			}
			channelDiscountDTO.setState(state);
			convertDescription(channelDiscount, channelDiscountDTO);
			
			channelDiscountDTOs.add(channelDiscountDTO);
		}

        return CommonPage.copyPageInfo(storeProductPage, channelDiscountDTOs);
	}

	/**
	 * 新增或修改
	 */
	@Transactional(rollbackFor = Exception.class)
	@Override
	public Boolean saveEntity(Integer merId, ChannelDiscountDTO channelDiscountDTO) {
		try {
			// 删除商品数据
			Integer id = channelDiscountDTO.getId();
			if(null != id) {
				log.info("--------------- 更新删除满减对应商品数据: {} ---------------", id);
				channelDiscountGoodsService.remove(Wrappers.<ChannelDiscountGoods>lambdaUpdate()
						.eq(ChannelDiscountGoods :: getDiscountId, id)
						);
			} else {
				channelDiscountDTO.setCreateUser(systemAdminService.getAdminId());
				channelDiscountDTO.setCreateTime(new Date());
			}
			
			// 主表数据处理
			ChannelDiscount channelDiscount = new ChannelDiscount();
			BeanUtils.copyProperties(channelDiscountDTO, channelDiscount);
			channelDiscount.setMerId(merId);
			this.saveOrUpdate(channelDiscount);
			id = channelDiscount.getId();
			
			// 赠品数据处理
			if(2 == channelDiscountDTO.getType()) {
				ChannelDiscountGoods channelDiscountGoods = new ChannelDiscountGoods();
				channelDiscountGoods.setDiscountId(id);
				channelDiscountGoods.setGoodsId(channelDiscountDTO.getGiftGoodsId());
				channelDiscountGoods.setGoodsType(2); // 指定商品
				channelDiscountGoods.setType(2); // 赠品
				channelDiscountGoods.setMerId(merId);
				channelDiscountGoods.setCreateTime(new Date());
				channelDiscountGoodsService.save(channelDiscountGoods);
			}
			
			// 对应商品数据处理
			if(1 != channelDiscountDTO.getGoodsType()) {
				List<Integer> goodsIds = channelDiscountDTO.getGoodsIds();
				List<ChannelDiscountGoods> channelDiscountGoodsList = new ArrayList<>();
				for(Integer goodsId : goodsIds) {
					ChannelDiscountGoods channelDiscountGoods = new ChannelDiscountGoods();
					channelDiscountGoods.setDiscountId(id);
					channelDiscountGoods.setGoodsId(goodsId);
					channelDiscountGoods.setGoodsType(channelDiscountDTO.getGoodsType());
					channelDiscountGoods.setType(1); // 活动商品
					channelDiscountGoods.setMerId(merId);
					channelDiscountGoods.setCreateTime(new Date());
					channelDiscountGoodsList.add(channelDiscountGoods);
				}
				channelDiscountGoodsService.saveBatch(channelDiscountGoodsList);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return true;
	}

	/**
	 * 删除
	 */
	@Transactional(rollbackFor = Exception.class)
	@Override
	public Boolean delEntity(Integer merId, Integer id) {
		log.info("--------------- 删除满减对应商品数据: {} ---------------", id);
		channelDiscountGoodsService.remove(Wrappers.<ChannelDiscountGoods>lambdaUpdate()
				.eq(ChannelDiscountGoods :: getDiscountId, id)
				);

        ChannelDiscount channelDiscountDB = this.getOne(Wrappers.<ChannelDiscount>lambdaQuery()
                .eq(ChannelDiscount :: getMerId, merId)
                .eq(ChannelDiscount :: getId, id)
                .last("LIMIT 1")
                );
        if(null == channelDiscountDB) {
    		throw new CrmebException("记录不存在");
        }
        
		return this.removeById(id);
	}

	/**
	 * 通过id获取活动详情
	 */
	@Override
	public ChannelDiscountDTO getEntity(Integer merId, Integer id) {
    	ChannelDiscount channelDiscountDB = this.getOne(Wrappers.<ChannelDiscount>lambdaQuery()
    			.eq(ChannelDiscount :: getMerId, merId)
    			.eq(ChannelDiscount :: getId, id)
    			.last("LIMIT 1")
    			);
    	if(null == channelDiscountDB) {
    		throw new CrmebException("记录不存在");
    	}

        // 对象复制
        ChannelDiscountDTO dto = new ChannelDiscountDTO();
        BeanUtils.copyProperties(channelDiscountDB, dto);
		convertDescription(channelDiscountDB, dto);
        // 查询对应活动商品id
        List<ChannelDiscountGoods> channelDiscountGoodsList = channelDiscountGoodsService.list(Wrappers.<ChannelDiscountGoods>lambdaQuery()
        		.eq(ChannelDiscountGoods :: getDiscountId, id)
        		);
        List<Integer> goodsIds = new ArrayList<>();
        for(ChannelDiscountGoods goods : channelDiscountGoodsList) {
        	Integer goodsId = goods.getGoodsId();
        	if(2 == goods.getType()) {
        		dto.setGiftGoodsId(goodsId);
        		dto.setGiftGoods(storeProductService.getById(goodsId));
        	} else {
        		goodsIds.add(goodsId);
        	}
        }
        dto.setGoodsIds(goodsIds);
        // 查询对应活动商品对象
        if(CollectionUtils.isNotEmpty(goodsIds)) {
        	List<StoreProduct> storeProducts = storeProductService.list(Wrappers.<StoreProduct>lambdaQuery()
        			.in(StoreProduct :: getId, goodsIds)
        			);
        	productConvertUtil.convertProductImage(storeProducts);
        	dto.setGoodsList(storeProducts);
        }
        
		return dto;
	}

	/**
	 * 判断商品是否在满减活动中
	 */
	@Override
	public ChannelDiscountDTO checkGoods2ChannelDiscount(Integer merId, Integer id, List<ChannelDiscountDTO> channelDiscountDTOs) {
		// 注意: 为null时才是需要查询的
		if(null == channelDiscountDTOs) {
			// 查询商家满减送活动
			ChannelDiscountRequest channelDiscountRequest = new ChannelDiscountRequest();
			channelDiscountRequest.setState(1);
			channelDiscountRequest.setStatus(true);
			channelDiscountDTOs = this.listEntity(merId, channelDiscountRequest);
		}

		// 满减送活动
		for(ChannelDiscountDTO channelDiscountDTO : channelDiscountDTOs) {
			List<ChannelDiscountGoods> channelDiscountGoods = Optional.ofNullable(channelDiscountDTO.getChannelDiscountGoodsList()).orElse(new ArrayList<>()).stream().filter(e -> e.getType() == 2).filter(e -> Objects.nonNull(e.getGoodsId())).collect(Collectors.toList());
			for (ChannelDiscountGoods good : channelDiscountGoods) {
				Integer goodsId = good.getGoodsId();
				if(2 == good.getType()) {
					StoreProduct giftGoods = storeProductService.getById(goodsId);
					channelDiscountDTO.setGiftGoodsId(goodsId);
					channelDiscountDTO.setGiftGoods(giftGoods);
					if (Objects.nonNull(giftGoods)) {
						productConvertUtil.convertProductImage(Arrays.asList(channelDiscountDTO.getGiftGoods()));
					}
				}
			}
			// 所有商品
			if(1 == channelDiscountDTO.getGoodsType()) {
				return channelDiscountDTO;
			// 不参与商品
			} else if(3 == channelDiscountDTO.getGoodsType()) {
				List<ChannelDiscountGoods> channelDiscountGoodsList = channelDiscountDTO.getChannelDiscountGoodsList();
				if(CollectionUtils.isEmpty(channelDiscountGoodsList)) {
					return channelDiscountDTO;
				}
				List<Integer> discountGoodsIds = channelDiscountGoodsList.stream().filter(e -> !e.getType().equals(2)).map(ChannelDiscountGoods::getGoodsId).filter(Objects::nonNull).collect(Collectors.toList());
				if(!discountGoodsIds.contains(id)) {
					return channelDiscountDTO;
				}
			// 指定参与商品
			} else if(2 == channelDiscountDTO.getGoodsType()) {
				List<ChannelDiscountGoods> channelDiscountGoodsList = channelDiscountDTO.getChannelDiscountGoodsList();
				if(CollectionUtils.isEmpty(channelDiscountGoodsList)) {
					continue;
				}
				List<Integer> discountGoodsIds = channelDiscountGoodsList.stream().filter(e -> !e.getType().equals(2)).map(ChannelDiscountGoods::getGoodsId).filter(Objects::nonNull).collect(Collectors.toList());
				if(discountGoodsIds.contains(id)) {
					return channelDiscountDTO;
				}
			}
		}
		
		return new ChannelDiscountDTO();
	}

	/**
	 * 功能描述: 转义为文本描述
	 * @Param: [channelDiscount, dto]
	 * @Return: void
	 * @Author: wangzh
	 * @Date: 2023/2/21 15:43
	 */
	private void convertDescription(ChannelDiscount channelDiscount, ChannelDiscountDTO dto) {
		// 转义为文本描述
		String type = 1 == channelDiscount.getType() ? "满{}元{}" : "满{}件{}"; // 活动类型
		Integer conditionType = channelDiscount.getConditionType().intValue(); //金额或件数
		String discountType = 1 == channelDiscount.getDiscountType() ? "减{}元" : "打{}折";
		BigDecimal discount = channelDiscount.getDiscount(); // 折扣内容
		String content = "";
		if (Objects.nonNull(discount)){
			content = StrUtil.format(discountType, discount.stripTrailingZeros().toPlainString());
		} else {
			content = "送赠品";
		}
		String description = StrUtil.format(type, conditionType, content);
		dto.setDescription(description);
	}

}
